﻿using CommunityToolkit.Mvvm.ComponentModel;
using MeasureAbstract.Base;
using MeasureAbstract.IFarfieldMeasure;
using Newtonsoft.Json;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Concurrent;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace MeasureAbstract.IRCSMeasure
{
    /// <summary>
    /// RCS测试的接口
    /// 测量数据应该是不同姿态下，某个频点的功率 姿态由球坐标（方位，俯仰，极化） 和3维直角坐标（x面向被测物从左至右,y面向被测物从下至上,z面向被测物从近至远）确定  
    /// 测量数据为对数幅度，相位，等
    /// </summary>
    [INotifyPropertyChanged]
    public abstract partial class IRCSMeasure : IMeasureBase
    {
        /// <summary>
        /// 测量名称
        /// </summary>
        public abstract string MeasureName { get; }

        /// <summary>
        /// 测量描述
        /// </summary>
        public abstract string Description { get; }

        /// <summary>
        /// 本DLL的版本号
        /// </summary>
        public abstract string Version { get; }

        /// <summary>
        /// 测量用到的设备列表
        /// </summary>
        private ObservableCollection<IDeviceBase> _DeviceList;
        public ObservableCollection<IDeviceBase> DeviceList
        {
            get { return _DeviceList; }
            set { SetProperty(ref _DeviceList, value); }
        }

        /// <summary>
        /// 测量进度
        /// </summary>
        public abstract double Process { get; set; }

        /// <summary>
        /// 继续测量
        /// </summary>
        public abstract void MeasureContinue();

        /// <summary>
        /// 测量初始化
        /// </summary>
        public abstract Task MeasureInitialize(object obj);

        /// <summary>
        /// 暂停测量
        /// </summary>
        public abstract void MeasurePause();

        /// <summary>
        /// 重置测量
        /// </summary>
        public abstract void MeasureReset();

        /// <summary>
        /// 开始测量
        /// </summary>
        /// <param name="Type"></param>
        /// <returns></returns>
        public abstract Task MeasureStart(object Type);

        /// <summary>
        /// 停止测量
        /// </summary>
        public abstract void MeasureStop();

        /// <summary>
        /// 保存数据
        /// </summary>
        public abstract void SaveData(object obj);









        //测量过程相关


        //测量类型 点频测量还是扫频测量
        public abstract string Type { get; set; }

        


        //安全相关过程处理





        //测量信息相关






        //不确定度相关




        [ObservableProperty]
        private string antennaName = "";

        [ObservableProperty]
        private string antennaModel = "";

        [ObservableProperty]
        private string polarizationDirection = "水平极化";

        [ObservableProperty]
        private string note = "";


        [ObservableProperty]
        private bool realTimeSave = true;

        [ObservableProperty]
        private string fileName = DateTime.Now.ToString("yyyyMMddHHmm");

        [ObservableProperty]
        private string fileType = "txt";

        /// <summary>
        /// 文件保存路径
        /// </summary>
        [ObservableProperty]
        private string dataFilePath = "";

        public ManualResetEvent ManualResetEvent = new ManualResetEvent(true);
        public bool StopFlag = false;
        public bool InitBreak = false;

        public MeasureData MeasureData = new MeasureData();
        public MeasureData2D MeasureData2D = new MeasureData2D();
        public RealTimeCache RealTimeCache = new RealTimeCache();
        public RealTimeCache2D RealTimeCache2D = new RealTimeCache2D();

        //可能用到的外部数据
        public dynamic SystemConfig { get; set; }
        public dynamic ExternalData { get; set; }


        //数据记录
        /// <summary>
        /// 数据记录，频率响应时用
        /// </summary>
        public Dictionary<double, ObservableCollection<DataItem>> DataDictPosition_FrequencyCollection;

        /// <summary>
        /// 数据记录
        /// </summary>
        public Dictionary<double, ObservableCollection<DataItem>> DataDictFrequency_PositionCollection;

        [ObservableProperty]
        private ObservableCollection<double> frequencyList;

        /// <summary>
        /// 生成报告
        /// </summary>
        [ObservableProperty]
        private IReport.IReport report;


    }

    public class DataItem2D : ObservableObject
    {
        /// <summary>
        /// 位置
        /// </summary>
        [DisplayName("位置1")]
        public double Position1
        {
            get { return _Position1; }
            set { SetProperty(ref _Position1, value); }
        }
        private double _Position1 = 0d;

        /// <summary>
        /// 位置
        /// </summary>
        [DisplayName("位置2")]
        public double Position2
        {
            get { return _Position2; }
            set { SetProperty(ref _Position2, value); }
        }
        private double _Position2 = 0d;

        /// <summary>
        /// 频率
        /// </summary>
        /// 
        [DisplayName("频率")]
        public double Frequency
        {
            get { return _Frequency; }
            set { SetProperty(ref _Frequency, value); }
        }
        private double _Frequency = 0d;

        /// <summary>
        /// 幅度值
        /// </summary>
        [DisplayName("对数幅度")]
        public double LogarithmicAmplitude
        {
            get { return _LogarithmicAmplitude; }
            set { SetProperty(ref _LogarithmicAmplitude, value); }


        }

        private double _LogarithmicAmplitude = 0;

        /// <summary>
        /// 相位值
        /// </summary>
        [DisplayName("相位")]
        public double Phase
        {
            get { return _Phase; }
            set { SetProperty(ref _Phase, value); }
        }
        private double _Phase = 0;

        [DisplayName("线性幅度")]
        public double LinearAmplitude
        {
            get { return _LinearAmplitude; }
            set { SetProperty(ref _LinearAmplitude, value); }
        }
        private double _LinearAmplitude = 0d;

        [DisplayName("实部")]
        public double RealPart
        {
            get { return _RealPart; }
            set { SetProperty(ref _RealPart, value); }
        }
        private double _RealPart = 0;

        [DisplayName("虚部")]
        public double ImaginaryPart
        {
            get { return _ImaginaryPart; }
            set { SetProperty(ref _ImaginaryPart, value); }
        }
        private double _ImaginaryPart = 0;

        [DisplayName("驻波比")]
        public double StandingWaveRatio
        {
            get { return _StandingWaveRatio; }
            set { SetProperty(ref _StandingWaveRatio, value); }
        }
        private double _StandingWaveRatio = 0;

        [DisplayName("群延时")]
        public double GroupDelay
        {
            get { return _GroupDelay; }
            set { SetProperty(ref _GroupDelay, value); }
        }
        public double _GroupDelay = 0;

    }
    public class MeasureData2D
    {
        public string MeasurementTime { get; set; } = "";
        public string MeasurementType { get; set; } = "";
        public string MeasurementParameter { get; set; } = "";
        public string DataFormat { get; set; } = "";
        public string AntennaIdentification { get; set; } = "";
        public string PolarizationDirection { get; set; } = "";
        public string MeasurementPersonel { get; set; } = "";
        public string Note { get; set; } = "";
        public string DocumentIdentificationMark { get; set; } = "CP_DATA";
        public string Reserve { get; set; } = "";
        public ObservableCollection<DataItem2D>? DataItems2D { get; set; }
    }

    public class DataItem : ObservableObject
    {
        /// <summary>
        /// 位置
        /// </summary>
        [DisplayName("位置")]
        public double Position
        {
            get { return _Position; }
            set { SetProperty(ref _Position, value); }
        }
        private double _Position = 0d;

        /// <summary>
        /// 频率
        /// </summary>
        /// 
        [DisplayName("频率")]
        public double Frequency
        {
            get { return _Frequency; }
            set { SetProperty(ref _Frequency, value); }
        }
        private double _Frequency = 0d;

        /// <summary>
        /// 幅度值
        /// </summary>
        [DisplayName("对数幅度")]
        public double LogarithmicAmplitude
        {
            get { return _LogarithmicAmplitude; }
            set { SetProperty(ref _LogarithmicAmplitude, value); }


        }

        private double _LogarithmicAmplitude = 0;

        /// <summary>
        /// 相位值
        /// </summary>
        [DisplayName("相位")]
        public double Phase
        {
            get { return _Phase; }
            set { SetProperty(ref _Phase, value); }
        }
        private double _Phase = 0;

        [DisplayName("线性幅度")]
        public double LinearAmplitude
        {
            get { return _LinearAmplitude; }
            set { SetProperty(ref _LinearAmplitude, value); }
        }
        private double _LinearAmplitude = 0d;

        [DisplayName("实部")]
        public double RealPart
        {
            get { return _RealPart; }
            set { SetProperty(ref _RealPart, value); }
        }
        private double _RealPart = 0;

        [DisplayName("虚部")]
        public double ImaginaryPart
        {
            get { return _ImaginaryPart; }
            set { SetProperty(ref _ImaginaryPart, value); }
        }
        private double _ImaginaryPart = 0;

        [DisplayName("驻波比")]
        public double StandingWaveRatio
        {
            get { return _StandingWaveRatio; }
            set { SetProperty(ref _StandingWaveRatio, value); }
        }
        private double _StandingWaveRatio = 0;

        [DisplayName("群延时")]
        public double GroupDelay
        {
            get { return _GroupDelay; }
            set { SetProperty(ref _GroupDelay, value); }
        }
        public double _GroupDelay = 0;

    }
    public class MeasureData
    {
        public string MeasurementTime { get; set; } = "";
        public string MeasurementType { get; set; } = "";
        public string MeasurementParameter { get; set; } = "";
        public string DataFormat { get; set; } = "";
        public string AntennaIdentification { get; set; } = "";
        public string PolarizationDirection { get; set; } = "";
        public string MeasurementPersonel { get; set; } = "";
        public string Note { get; set; } = "";
        public string DocumentIdentificationMark { get; set; } = "CP_DATA";
        public string Reserve { get; set; } = "";
        public ObservableCollection<DataItem>? DataItems { get; set; }
    }

    public static class DataManage
    {
        public static void FromPositionBaseDictToFrequencyBaseDict(ref Dictionary<double, ObservableCollection<DataItem>> PositionBaseDataDict, ref Dictionary<double, ObservableCollection<DataItem>> FrequencyBaseDataDict)
        {
            if (PositionBaseDataDict == null)
            {
                throw new ArgumentNullException(nameof(PositionBaseDataDict));
            }
            if (FrequencyBaseDataDict == null)
            {
                FrequencyBaseDataDict = new Dictionary<double, ObservableCollection<DataItem>>();
            }
            FrequencyBaseDataDict.Clear();
            foreach (var Item in PositionBaseDataDict.Values)
            {
                if (Item != null)
                {
                    foreach (var DataItem in Item)
                    {
                        AddDataItemToFrequencyBaseDict(DataItem, ref FrequencyBaseDataDict);
                    }
                }
            }
        }

        public static void FromFrequencyBaseDictToPositionBaseDict(ref Dictionary<double, ObservableCollection<DataItem>> FrequencyBaseDataDict, ref Dictionary<double, ObservableCollection<DataItem>> PositionBaseDataDict)
        {
            if (FrequencyBaseDataDict == null)
            {
                throw new ArgumentNullException(nameof(FrequencyBaseDataDict));
            }
            if (PositionBaseDataDict == null)
            {
                PositionBaseDataDict = new Dictionary<double, ObservableCollection<DataItem>>();
            }
            PositionBaseDataDict.Clear();
            foreach (var Item in FrequencyBaseDataDict.Values)
            {
                if (Item != null)
                {
                    foreach (var DataItem in Item)
                    {
                        AddDataItemToPositionBaseDict(DataItem, ref PositionBaseDataDict);
                    }
                }
            }
        }

        public static void AddDataItemToPositionBaseDict(DataItem Item, ref Dictionary<double, ObservableCollection<DataItem>> PositionBaseDict)
        {
            if (PositionBaseDict == null)
            {
                PositionBaseDict = new Dictionary<double, ObservableCollection<DataItem>>();
            }
            if (Item == null)
            {
                throw new ArgumentNullException(nameof(Item));
            }

            double Position = Item.Position;

            if (PositionBaseDict.Keys.Contains(Position))
            {
                if (PositionBaseDict[Position] == null)
                {
                    PositionBaseDict[Position] = new ObservableCollection<DataItem>();
                }
                PositionBaseDict[Position].Add(Item);
            }
            else
            {
                PositionBaseDict.Add(Position, new ObservableCollection<DataItem> { Item });
            }
        }

        public static void AddDataItemToFrequencyBaseDict(DataItem Item, ref Dictionary<double, ObservableCollection<DataItem>> FrequencyBaseDict)
        {
            if (FrequencyBaseDict == null)
            {
                FrequencyBaseDict = new Dictionary<double, ObservableCollection<DataItem>>();
            }
            if (Item == null)
            {
                throw new ArgumentNullException(nameof(Item));
            }

            double Frequency = Item.Frequency;

            if (FrequencyBaseDict.Keys.Contains(Frequency))
            {
                if (FrequencyBaseDict[Frequency] == null)
                {
                    FrequencyBaseDict[Frequency] = new ObservableCollection<DataItem>();
                }
                FrequencyBaseDict[Frequency].Add(Item);
            }
            else
            {
                FrequencyBaseDict.Add(Frequency, new ObservableCollection<DataItem> { Item });
            }
        }

        public static void WriteToFile<T>(T MeasureData, string FileFullName) where T : class
        {
            //验证参数
            if (MeasureData == null)
            {
                throw new ArgumentNullException(nameof(MeasureData));
            }
            if (string.IsNullOrEmpty(FileFullName))
            {
                throw new Exception("File name can not be null!");
            }
            string[] FileStr = FileFullName.Split(".");
            string FileType = FileStr.Last();
            if (string.IsNullOrEmpty(FileType))
            {
                throw new Exception($"File name error,not contain the extension name!\n{FileFullName}");
            }
            if (!"TXT,CSV,XLSX,XLS,JSON,XML,".Contains(FileType.ToUpper() + ","))
            {
                throw new Exception($"Unsupported file type:{FileType}!");
            }
            //验证文件名是否合法
            if (FileFullName.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0)
            {
                //File name is illegal
                throw new ArgumentException($"File name is illegal:\n{FileFullName}");
            }
            if (System.IO.File.Exists(FileFullName))
            {
                throw new Exception($"File already exists!\n{FileFullName}");
            }
            //创建目录
            FileStr = FileFullName.Split("\\");
            string FileName = FileStr.Last();
            if (!System.IO.Directory.Exists(FileFullName.Replace(FileName, "")))
            {
                System.IO.Directory.CreateDirectory(FileFullName.Replace(FileName, ""));
            }

            if (FileType.ToUpper() == "JSON")
            {
                string Json = JsonConvert.SerializeObject(MeasureData, Newtonsoft.Json.Formatting.Indented);
                System.IO.File.WriteAllText(FileFullName, Json);
            }
            else if (FileType.ToUpper() == "XML")
            {
                FileStream FileStream = new FileStream(FileFullName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
                XmlWriterSettings XmlWriterSettings = new XmlWriterSettings() { Indent = true, Encoding = Encoding.UTF8 };
                XmlWriter XmlWriter = XmlWriter.Create(FileStream, XmlWriterSettings);
                XmlSerializer XmlSerializer = new XmlSerializer(typeof(T));
                XmlSerializer.Serialize(XmlWriter, MeasureData);
                FileStream.Close();
            }
            else if (FileType.ToUpper() == "TXT" || FileType.ToUpper() == "CSV")
            {
                bool IsTitle = true;
                Type type = typeof(MeasureData);
                List<string> Temp = new List<string>();
                PropertyInfo[] PropertyInfo = type.GetProperties();
                foreach (PropertyInfo Property in PropertyInfo)
                {
                    object? value;
                    if (typeof(ICollection).IsAssignableFrom(Property.PropertyType))
                    {
                        value = Property.GetValue(MeasureData, null);
                        if (value != null)
                        {
                            if (((ICollection)value).Count > 0)
                            {
                                foreach (var temp in (ICollection)value)
                                {
                                    string str = "";

                                    if (IsTitle)
                                    {
                                        //第一次添加标题
                                        Type type2 = temp.GetType();
                                        PropertyInfo[] PropertyInfo2 = type2.GetProperties();
                                        foreach (PropertyInfo Property2 in PropertyInfo2)
                                        {
                                            var attr = Property2.GetCustomAttribute<DisplayNameAttribute>(false);
                                            if (attr == null)
                                            {
                                                str += PadRightEx("", 25);
                                            }
                                            else
                                            {
                                                str += PadRightEx(attr.DisplayName, 25);
                                            }
                                            str += ",";
                                        }
                                        str += "\n";
                                        IsTitle = false;
                                    }

                                    Type type1 = temp.GetType();
                                    PropertyInfo[] PropertyInfo1 = type1.GetProperties();
                                    foreach (PropertyInfo Property1 in PropertyInfo1)
                                    {
                                        value = Property1.GetValue(temp, null);
                                        if (value == null)
                                        {
                                            str += PadRightEx("", 25);
                                        }
                                        else
                                        {
                                            str += PadRightEx(value.ToString(), 25);
                                        }
                                        str += ",";
                                    }
                                    Temp.Add(str);
                                }
                            }
                        }
                    }
                    else
                    {
                        value = Property.GetValue(MeasureData, null);
                        if (value == null)
                        {
                            Temp.Add("");
                        }
                        else
                        {
                            Temp.Add($"{value.ToString()}");
                        }
                    }
                }
                StreamWriter StreamWriter = File.AppendText(FileFullName);
                foreach (string data in Temp)
                {
                    StreamWriter.WriteLine(data);
                }
                StreamWriter.Flush();
                StreamWriter.Close();
                StreamWriter.Dispose();
            }
            else if (FileType.ToUpper() == "XLSX" || FileType.ToUpper() == "XLS")
            {
                bool IsTitle = true;
                Type type = typeof(T);
                List<List<string>> Temp = new List<List<string>>();
                PropertyInfo[] PropertyInfo = type.GetProperties();
                foreach (PropertyInfo Property in PropertyInfo)
                {
                    object? value;
                    if (typeof(ICollection).IsAssignableFrom(Property.PropertyType))
                    {
                        value = Property.GetValue(MeasureData, null);
                        if (value != null)
                        {
                            if (((ICollection)value).Count > 0)
                            {
                                foreach (var temp in (ICollection)value)
                                {
                                    if (IsTitle)
                                    {
                                        //添加标题
                                        List<string> te2 = new List<string>();
                                        Type type2 = temp.GetType();
                                        PropertyInfo[] PropertyInfo2 = type2.GetProperties();
                                        //string str = "";
                                        foreach (PropertyInfo Property2 in PropertyInfo2)
                                        {
                                            var attr = Property2.GetCustomAttribute<DisplayNameAttribute>(false);
                                            if (attr == null)
                                            {
                                                te2.Add("");
                                            }
                                            else
                                            {
                                                te2.Add(attr.DisplayName);
                                            }
                                        }
                                        Temp.Add(te2);
                                        IsTitle = false;
                                    }
                                    List<string> te = new List<string>();
                                    Type type1 = temp.GetType();
                                    PropertyInfo[] PropertyInfo1 = type1.GetProperties();
                                    //string str = "";
                                    foreach (PropertyInfo Property1 in PropertyInfo1)
                                    {
                                        value = Property1.GetValue(temp, null);
                                        if (value == null)
                                        {
                                            te.Add("");
                                        }
                                        else
                                        {
                                            te.Add(value.ToString());
                                        }
                                    }
                                    Temp.Add(te);
                                }
                            }
                        }
                    }
                    else
                    {
                        value = Property.GetValue(MeasureData, null);
                        if (value == null)
                        {
                            Temp.Add(new List<string>() { "" });
                        }
                        else
                        {
                            Temp.Add(new List<string>() { $"{value.ToString()}" });
                        }
                    }
                }

                if (FileType.ToUpper() == "XLSX")
                {
                    XSSFWorkbook WB = new XSSFWorkbook();
                    var style = WB.CreateCellStyle();
                    style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; // 设置水平居中
                    style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center; // 设置垂直居中

                    ISheet Sheet = WB.CreateSheet("测量数据");
                    IsTitle = true;
                    for (int i = 0; i < Temp.Count; i++)
                    {
                        IRow Row = Sheet.CreateRow(i);
                        if (Temp[i] != null)
                        {
                            if (Temp[i].Count == 1)
                            {
                                ICell Cell = Row.CreateCell(0);
                                Cell.SetCellType(CellType.String);
                                Cell.SetCellValue(Temp[i][0]);

                            }
                            else if (Temp[i].Count > 1)
                            {
                                if (IsTitle)
                                {
                                    for (int j = 0; j < Temp[i].Count; j++)
                                    {
                                        ICell Cell = Row.CreateCell(j);
                                        double tt;
                                        Cell.CellStyle = style;
                                        Cell.SetCellType(CellType.String);
                                        Cell.SetCellValue(Temp[i][j]);

                                    }
                                    IsTitle = false;
                                }
                                else
                                {
                                    for (int j = 0; j < Temp[i].Count; j++)
                                    {
                                        ICell Cell = Row.CreateCell(j);
                                        double tt;
                                        Cell.CellStyle = style;
                                        Cell.SetCellType(CellType.Numeric);
                                        if (double.TryParse(Temp[i][j], out tt))
                                        {
                                            Cell.SetCellValue(tt);
                                        }
                                        else
                                        {
                                            Cell.SetCellValue(Temp[i][j]);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    //Sheet.ProtectSheet(Sheet.GetRow(0).GetCell(0).ToString()); //保护文档
                    Stream Stream = new FileStream(FileFullName, FileMode.Create, FileAccess.ReadWrite);
                    WB.Write(Stream);
                    Stream.Close();
                }
                if (FileType.ToUpper() == "XLS")
                {
                    HSSFWorkbook WB = new HSSFWorkbook();
                    var style = WB.CreateCellStyle();
                    style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; // 设置水平居中
                    style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center; // 设置垂直居中
                    ISheet Sheet = WB.CreateSheet("测量数据");
                    IsTitle = true;
                    for (int i = 0; i < Temp.Count; i++)
                    {
                        IRow Row = Sheet.CreateRow(i);
                        if (Temp[i] != null)
                        {
                            if (Temp[i].Count == 1)
                            {
                                ICell Cell = Row.CreateCell(0);
                                Cell.SetCellType(CellType.String);
                                Cell.SetCellValue(Temp[i][0]);

                            }
                            else if (Temp[i].Count > 1)
                            {
                                if (IsTitle)
                                {
                                    for (int j = 0; j < Temp[i].Count; j++)
                                    {
                                        ICell Cell = Row.CreateCell(j);
                                        double tt;
                                        Cell.CellStyle = style;
                                        Cell.SetCellType(CellType.String);
                                        Cell.SetCellValue(Temp[i][j]);

                                    }
                                    IsTitle = false;
                                }
                                else
                                {
                                    for (int j = 0; j < Temp[i].Count; j++)
                                    {
                                        ICell Cell = Row.CreateCell(j);
                                        double tt;
                                        Cell.CellStyle = style;
                                        Cell.SetCellType(CellType.Numeric);
                                        if (double.TryParse(Temp[i][j], out tt))
                                        {
                                            Cell.SetCellValue(tt);
                                        }
                                        else
                                        {
                                            Cell.SetCellValue(Temp[i][j]);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    //Sheet.ProtectSheet(Sheet.GetRow(0).GetCell(0).ToString()); //保护文档
                    Stream Stream = new FileStream(FileFullName, FileMode.Create, FileAccess.ReadWrite);
                    WB.Write(Stream);
                    Stream.Close();
                }
            }
        }

        public static void ReadFromFile(string FileFullName, out MeasureData MeasureData)
        {
            if (string.IsNullOrEmpty(FileFullName)) throw new ArgumentNullException(nameof(FileFullName));

            if (!File.Exists(FileFullName))
            {
                throw new FileNotFoundException($"{FileFullName} not exist!");
            }

            string[] FileStr = FileFullName.Split(".");
            string FileType = FileStr.Last();
            if (string.IsNullOrEmpty(FileType))
            {
                throw new Exception($"File name error,not contain the extension name!\n{FileFullName}");
            }
            if (!"TXT,CSV,XLSX,XLS,JSON,XML,".Contains(FileType.ToUpper() + ","))
            {
                throw new Exception($"Unsupported file type:{FileType}!");
            }

            if (FileType.ToUpper() == "JSON")
            {
                string datastring = System.IO.File.ReadAllText(FileFullName);
                MeasureData = JsonConvert.DeserializeObject<MeasureData>(datastring)!;
                if (MeasureData == null)
                {
                    throw new Exception($"Read file failed!");
                }
            }
            else if (FileType.ToUpper() == "XML")
            {
                FileStream FileStream = new FileStream(FileFullName, FileMode.Open, FileAccess.Read, FileShare.Read);
                XmlSerializer XmlSerializer = new XmlSerializer(typeof(MeasureData));
                MeasureData = (MeasureData)XmlSerializer.Deserialize(FileStream)!;
                FileStream.Close();
                if (MeasureData == null)
                {
                    throw new Exception($"Read file failed!");
                }
            }
            else if (FileType.ToUpper() == "TXT" || FileType.ToUpper() == "CSV")
            {
                MeasureData measureData = new MeasureData();
                string[] strs = System.IO.File.ReadAllLines(FileFullName);
                measureData.MeasurementTime = strs[0];
                measureData.MeasurementType = strs[1];
                measureData.MeasurementParameter = strs[2];
                measureData.DataFormat = strs[3];
                measureData.AntennaIdentification = strs[4];
                measureData.PolarizationDirection = strs[5];
                measureData.MeasurementPersonel = strs[6];
                measureData.Note = strs[7];
                measureData.DocumentIdentificationMark = strs[8];
                measureData.Reserve = strs[9];
                measureData.DataItems = new ObservableCollection<DataItem>();
                //解析列标题
                string[] Titles = strs[10].Split(",");

                Type type = typeof(DataItem);
                PropertyInfo[] PropertyInfo = type.GetProperties();
                for (int i = 11; i < strs.Length; i++)
                {
                    string[] sx = strs[i].Split(",");
                    DataItem DataItem = new DataItem();
                    for (int j = 0; j < sx.Length; j++)
                    {
                        //通过特性值给DataItem赋值
                        foreach (PropertyInfo Property in PropertyInfo)
                        {
                            var attr = Property.GetCustomAttribute<DisplayNameAttribute>(false);
                            if (attr == null) continue;
                            if (attr.DisplayName == Titles[j].Replace(" ", ""))
                            {
                                Property.SetValue(DataItem, double.Parse(sx[j]));
                                break;
                            }
                        }
                    }
                    measureData.DataItems.Add(DataItem);
                }
                MeasureData = measureData;
                if (MeasureData == null)
                {
                    throw new Exception($"Read file failed!");
                }
            }
            else if (FileType.ToUpper() == "XLSX")
            {
                MeasureData measureData = new MeasureData();

                XSSFWorkbook WB = new XSSFWorkbook(FileFullName);
                ISheet Sheet = WB.GetSheetAt(0);
                measureData.MeasurementTime = Sheet.GetRow(0).GetCell(0).StringCellValue;
                measureData.MeasurementType = Sheet.GetRow(1).GetCell(0).StringCellValue;
                measureData.MeasurementParameter = Sheet.GetRow(2).GetCell(0).StringCellValue;
                measureData.DataFormat = Sheet.GetRow(3).GetCell(0).StringCellValue;
                measureData.AntennaIdentification = Sheet.GetRow(4).GetCell(0).StringCellValue;
                measureData.PolarizationDirection = Sheet.GetRow(5).GetCell(0).StringCellValue;
                measureData.MeasurementPersonel = Sheet.GetRow(6).GetCell(0).StringCellValue;
                measureData.Note = Sheet.GetRow(7).GetCell(0).StringCellValue;
                measureData.DocumentIdentificationMark = Sheet.GetRow(8).GetCell(0).StringCellValue;
                measureData.Reserve = Sheet.GetRow(9).GetCell(0).StringCellValue;
                measureData.DataItems = new ObservableCollection<DataItem>();
                //解析标题
                var TitleRow = Sheet.GetRow(10);
                List<string> Titles = new List<string>();
                for (int i = 0; i < 100; i++)
                {
                    if (TitleRow.GetCell(i) == null)
                    {
                        break;
                    }
                    Titles.Add(TitleRow.GetCell(i).StringCellValue.Replace(" ", ""));
                }

                Type type = typeof(DataItem);
                PropertyInfo[] PropertyInfo = type.GetProperties();

                string temp = "";
                for (int i = 11; i < 1000000000; i++)//行
                {
                    DataItem DataItem = new DataItem();
                    if (Sheet.GetRow(i) == null)
                    {
                        break;//读取完毕
                    }
                    if (Sheet.GetRow(i).GetCell(0) == null)
                    {
                        //读取完毕
                        break;
                    }
                    if (Sheet.GetRow(i).GetCell(0).ToString() == "")
                    {
                        //读取完毕
                        break;
                    }
                    for (int j = 0; j < Titles.Count; j++)
                    {
                        //通过特性值给DataItem赋值
                        foreach (PropertyInfo Property in PropertyInfo)
                        {
                            var attr = Property.GetCustomAttribute<DisplayNameAttribute>(false);
                            if (attr == null) continue;
                            if (attr.DisplayName == Titles[j].Replace(" ", ""))
                            {

                                Property.SetValue(DataItem, double.Parse(Sheet.GetRow(i).GetCell(j).ToString() == "" ? "0" : Sheet.GetRow(i).GetCell(j).ToString()));
                                break;
                            }
                        }

                    }
                    measureData.DataItems.Add(DataItem);
                }
                MeasureData = measureData;
                if (MeasureData == null)
                {
                    WB.Close();
                    throw new Exception($"Read file failed!");
                }
                WB.Close();
            }
            else if (FileType.ToUpper() == "XLS")
            {
                MeasureData measureData = new MeasureData();

                FileStream FileStream = new FileStream(FileFullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                HSSFWorkbook WB = new HSSFWorkbook(FileStream);
                FileStream.Close();
                ISheet Sheet = WB.GetSheetAt(0);
                measureData.MeasurementTime = Sheet.GetRow(0).GetCell(0).StringCellValue;
                measureData.MeasurementType = Sheet.GetRow(1).GetCell(0).StringCellValue;
                measureData.MeasurementParameter = Sheet.GetRow(2).GetCell(0).StringCellValue;
                measureData.DataFormat = Sheet.GetRow(3).GetCell(0).StringCellValue;
                measureData.AntennaIdentification = Sheet.GetRow(4).GetCell(0).StringCellValue;
                measureData.PolarizationDirection = Sheet.GetRow(5).GetCell(0).StringCellValue;
                measureData.MeasurementPersonel = Sheet.GetRow(6).GetCell(0).StringCellValue;
                measureData.Note = Sheet.GetRow(7).GetCell(0).StringCellValue;
                measureData.DocumentIdentificationMark = Sheet.GetRow(8).GetCell(0).StringCellValue;
                measureData.Reserve = Sheet.GetRow(9).GetCell(0).StringCellValue;
                measureData.DataItems = new ObservableCollection<DataItem>();
                //解析标题
                var TitleRow = Sheet.GetRow(10);
                List<string> Titles = new List<string>();
                for (int i = 0; i < 100; i++)
                {
                    if (TitleRow.GetCell(i) == null)
                    {
                        break;
                    }
                    Titles.Add(TitleRow.GetCell(i).StringCellValue.Replace(" ", ""));
                }

                Type type = typeof(DataItem);
                PropertyInfo[] PropertyInfo = type.GetProperties();

                string temp = "";
                for (int i = 11; i < 1000000000; i++)//行
                {
                    DataItem DataItem = new DataItem();
                    if (Sheet.GetRow(i) == null)
                    {
                        break;//读取完毕
                    }

                    for (int j = 0; j < Titles.Count; j++)
                    {
                        //通过特性值给DataItem赋值
                        foreach (PropertyInfo Property in PropertyInfo)
                        {
                            var attr = Property.GetCustomAttribute<DisplayNameAttribute>(false);
                            if (attr == null) continue;
                            if (attr.DisplayName == Titles[j].Replace(" ", ""))
                            {
                                Property.SetValue(DataItem, double.Parse(Sheet.GetRow(i).GetCell(j).ToString()));
                                break;
                            }
                        }

                    }
                    measureData.DataItems.Add(DataItem);
                }
                MeasureData = measureData;
                if (MeasureData == null)
                {
                    throw new Exception($"Read file failed!");
                }
            }
            else
            {
                throw new Exception($"Unsupported file type:{FileType}!");
            }
        }

        public static void ReadFromFile(string FileFullName, out MeasureData2D MeasureData2D)
        {
            if (string.IsNullOrEmpty(FileFullName)) throw new ArgumentNullException(nameof(FileFullName));

            if (!File.Exists(FileFullName))
            {
                throw new FileNotFoundException($"{FileFullName} not exist!");
            }

            string[] FileStr = FileFullName.Split(".");
            string FileType = FileStr.Last();
            if (string.IsNullOrEmpty(FileType))
            {
                throw new Exception($"File name error,not contain the extension name!\n{FileFullName}");
            }
            if (!"TXT,CSV,XLSX,XLS,JSON,XML,".Contains(FileType.ToUpper() + ","))
            {
                throw new Exception($"Unsupported file type:{FileType}!");
            }

            if (FileType.ToUpper() == "JSON")
            {
                string datastring = System.IO.File.ReadAllText(FileFullName);
                MeasureData2D = JsonConvert.DeserializeObject<MeasureData2D>(datastring)!;
                if (MeasureData2D == null)
                {
                    throw new Exception($"Read file failed!");
                }
            }
            else if (FileType.ToUpper() == "XML")
            {
                FileStream FileStream = new FileStream(FileFullName, FileMode.Open, FileAccess.Read, FileShare.Read);
                XmlSerializer XmlSerializer = new XmlSerializer(typeof(MeasureData));
                MeasureData2D = (MeasureData2D)XmlSerializer.Deserialize(FileStream)!;
                FileStream.Close();
                if (MeasureData2D == null)
                {
                    throw new Exception($"Read file failed!");
                }
            }
            else if (FileType.ToUpper() == "TXT" || FileType.ToUpper() == "CSV")
            {
                MeasureData2D measureData2D = new MeasureData2D();
                string[] strs = System.IO.File.ReadAllLines(FileFullName);
                measureData2D.MeasurementTime = strs[0];
                measureData2D.MeasurementType = strs[1];
                measureData2D.MeasurementParameter = strs[2];
                measureData2D.DataFormat = strs[3];
                measureData2D.AntennaIdentification = strs[4];
                measureData2D.PolarizationDirection = strs[5];
                measureData2D.MeasurementPersonel = strs[6];
                measureData2D.Note = strs[7];
                measureData2D.DocumentIdentificationMark = strs[8];
                measureData2D.Reserve = strs[9];
                measureData2D.DataItems2D = new ObservableCollection<DataItem2D>();
                //解析列标题
                string[] Titles = strs[10].Split(",");

                Type type = typeof(DataItem);
                PropertyInfo[] PropertyInfo = type.GetProperties();
                for (int i = 11; i < strs.Length; i++)
                {
                    string[] sx = strs[i].Split(",");
                    DataItem2D DataItem2D = new DataItem2D();
                    for (int j = 0; j < sx.Length; j++)
                    {
                        //通过特性值给DataItem赋值
                        foreach (PropertyInfo Property in PropertyInfo)
                        {
                            var attr = Property.GetCustomAttribute<DisplayNameAttribute>(false);
                            if (attr == null) continue;
                            if (attr.DisplayName == Titles[j].Replace(" ", ""))
                            {
                                Property.SetValue(DataItem2D, double.Parse(sx[j]));
                                break;
                            }
                        }
                    }
                    measureData2D.DataItems2D.Add(DataItem2D);
                }
                MeasureData2D = measureData2D;
                if (MeasureData2D == null)
                {
                    throw new Exception($"Read file failed!");
                }
            }
            else if (FileType.ToUpper() == "XLSX")
            {
                MeasureData2D measureData2D = new MeasureData2D();

                XSSFWorkbook WB = new XSSFWorkbook(FileFullName);
                ISheet Sheet = WB.GetSheetAt(0);
                measureData2D.MeasurementTime = Sheet.GetRow(0).GetCell(0).StringCellValue;
                measureData2D.MeasurementType = Sheet.GetRow(1).GetCell(0).StringCellValue;
                measureData2D.MeasurementParameter = Sheet.GetRow(2).GetCell(0).StringCellValue;
                measureData2D.DataFormat = Sheet.GetRow(3).GetCell(0).StringCellValue;
                measureData2D.AntennaIdentification = Sheet.GetRow(4).GetCell(0).StringCellValue;
                measureData2D.PolarizationDirection = Sheet.GetRow(5).GetCell(0).StringCellValue;
                measureData2D.MeasurementPersonel = Sheet.GetRow(6).GetCell(0).StringCellValue;
                measureData2D.Note = Sheet.GetRow(7).GetCell(0).StringCellValue;
                measureData2D.DocumentIdentificationMark = Sheet.GetRow(8).GetCell(0).StringCellValue;
                measureData2D.Reserve = Sheet.GetRow(9).GetCell(0).StringCellValue;
                measureData2D.DataItems2D = new ObservableCollection<DataItem2D>();
                //解析标题
                var TitleRow = Sheet.GetRow(10);
                List<string> Titles = new List<string>();
                for (int i = 0; i < 100; i++)
                {
                    if (TitleRow.GetCell(i) == null)
                    {
                        break;
                    }
                    Titles.Add(TitleRow.GetCell(i).StringCellValue.Replace(" ", ""));
                }

                Type type = typeof(DataItem);
                PropertyInfo[] PropertyInfo = type.GetProperties();

                string temp = "";
                for (int i = 11; i < 1000000000; i++)//行
                {
                    DataItem2D DataItem2D = new DataItem2D();
                    if (Sheet.GetRow(i) == null)
                    {
                        break;//读取完毕
                    }
                    if (Sheet.GetRow(i).GetCell(0) == null)
                    {
                        //读取完毕
                        break;
                    }
                    if (Sheet.GetRow(i).GetCell(0).ToString() == "")
                    {
                        //读取完毕
                        break;
                    }
                    for (int j = 0; j < Titles.Count; j++)
                    {
                        //通过特性值给DataItem赋值
                        foreach (PropertyInfo Property in PropertyInfo)
                        {
                            var attr = Property.GetCustomAttribute<DisplayNameAttribute>(false);
                            if (attr == null) continue;
                            if (attr.DisplayName == Titles[j].Replace(" ", ""))
                            {

                                Property.SetValue(DataItem2D, double.Parse(Sheet.GetRow(i).GetCell(j).ToString() == "" ? "0" : Sheet.GetRow(i).GetCell(j).ToString()));
                                break;
                            }
                        }

                    }
                    measureData2D.DataItems2D.Add(DataItem2D);
                }
                MeasureData2D = measureData2D;
                if (MeasureData2D == null)
                {
                    WB.Close();
                    throw new Exception($"Read file failed!");
                }
                WB.Close();
            }
            else if (FileType.ToUpper() == "XLS")
            {
                MeasureData2D measureData2D = new MeasureData2D();

                FileStream FileStream = new FileStream(FileFullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                HSSFWorkbook WB = new HSSFWorkbook(FileStream);
                FileStream.Close();
                ISheet Sheet = WB.GetSheetAt(0);
                measureData2D.MeasurementTime = Sheet.GetRow(0).GetCell(0).StringCellValue;
                measureData2D.MeasurementType = Sheet.GetRow(1).GetCell(0).StringCellValue;
                measureData2D.MeasurementParameter = Sheet.GetRow(2).GetCell(0).StringCellValue;
                measureData2D.DataFormat = Sheet.GetRow(3).GetCell(0).StringCellValue;
                measureData2D.AntennaIdentification = Sheet.GetRow(4).GetCell(0).StringCellValue;
                measureData2D.PolarizationDirection = Sheet.GetRow(5).GetCell(0).StringCellValue;
                measureData2D.MeasurementPersonel = Sheet.GetRow(6).GetCell(0).StringCellValue;
                measureData2D.Note = Sheet.GetRow(7).GetCell(0).StringCellValue;
                measureData2D.DocumentIdentificationMark = Sheet.GetRow(8).GetCell(0).StringCellValue;
                measureData2D.Reserve = Sheet.GetRow(9).GetCell(0).StringCellValue;
                measureData2D.DataItems2D = new ObservableCollection<DataItem2D>();
                //解析标题
                var TitleRow = Sheet.GetRow(10);
                List<string> Titles = new List<string>();
                for (int i = 0; i < 100; i++)
                {
                    if (TitleRow.GetCell(i) == null)
                    {
                        break;
                    }
                    Titles.Add(TitleRow.GetCell(i).StringCellValue.Replace(" ", ""));
                }

                Type type = typeof(DataItem);
                PropertyInfo[] PropertyInfo = type.GetProperties();

                string temp = "";
                for (int i = 11; i < 1000000000; i++)//行
                {
                    DataItem2D DataItem2D = new DataItem2D();
                    if (Sheet.GetRow(i) == null)
                    {
                        break;//读取完毕
                    }

                    for (int j = 0; j < Titles.Count; j++)
                    {
                        //通过特性值给DataItem赋值
                        foreach (PropertyInfo Property in PropertyInfo)
                        {
                            var attr = Property.GetCustomAttribute<DisplayNameAttribute>(false);
                            if (attr == null) continue;
                            if (attr.DisplayName == Titles[j].Replace(" ", ""))
                            {
                                Property.SetValue(DataItem2D, double.Parse(Sheet.GetRow(i).GetCell(j).ToString()));
                                break;
                            }
                        }

                    }
                    measureData2D.DataItems2D.Add(DataItem2D);
                }
                MeasureData2D = measureData2D;
                if (MeasureData2D == null)
                {
                    throw new Exception($"Read file failed!");
                }
            }
            else
            {
                throw new Exception($"Unsupported file type:{FileType}!");
            }
        }
        public static void AddOrUpdateFrequencySpectrumToPositionBaseDict(double Position, List<double> Values, List<double> FrequencyList, Action<DataItem, double> SetValue, ref Dictionary<double, ObservableCollection<DataItem>> PositionBaseDict)
        {
            if (Values == null)
            {
                throw new ArgumentNullException(nameof(Values));
            }
            if (FrequencyList == null)
            {
                throw new ArgumentNullException(nameof(FrequencyList));
            }
            if (Values.Count != FrequencyList.Count)
            {
                throw new Exception($"Frequency and values quantity inconsistency!");
            }
            if (SetValue == null)
            {
                throw new ArgumentNullException(nameof(SetValue));
            }
            if (PositionBaseDict == null)
            {
                PositionBaseDict = new Dictionary<double, ObservableCollection<DataItem>>();
            }
            if (!PositionBaseDict.Keys.Contains(Position))
            {
                PositionBaseDict.Add(Position, new ObservableCollection<DataItem>());
            }

            var Temp = PositionBaseDict[Position];
            for (int i = 0; i < FrequencyList.Count; i++)
            {
                var Items = Temp.Where(s => s.Frequency == FrequencyList[i]);

                if (Items == null)
                {
                    //当前频点不存在,新增
                    DataItem DataItem = new DataItem();
                    DataItem = new DataItem();
                    DataItem.Position = Position;
                    DataItem.Frequency = FrequencyList[i];
                    SetValue.Invoke(DataItem, Values[i]);
                    Temp.Add(DataItem);
                }
                else
                {
                    //当前频点已存在，更新
                    if (Items.ToList().Count == 1)
                    {
                        DataItem DataItem = Items.First();
                        SetValue.Invoke(DataItem, Values[i]);
                    }
                    else if (Items.ToList().Count == 0)
                    {
                        DataItem DataItem = new DataItem();
                        DataItem = new DataItem();
                        DataItem.Position = Position;
                        DataItem.Frequency = FrequencyList[i];
                        SetValue.Invoke(DataItem, Values[i]);
                        Temp.Add(DataItem);
                    }
                    else if (Items.ToList().Count > 1)
                    {
                        throw new Exception("The same frequency count exceed 1!");
                    }
                }
            }
        }

        public static void AddOrUpdateFrequencySpectrumToFrequencyBaseDict(double Position, List<double> Values, List<double> FrequencyList, Action<DataItem, double> SetValue, ref Dictionary<double, ObservableCollection<DataItem>> FrequencyBaseDict)
        {
            if (Values == null)
            {
                throw new ArgumentNullException(nameof(Values));
            }
            if (FrequencyList == null)
            {
                throw new ArgumentNullException(nameof(FrequencyList));
            }
            if (Values.Count != FrequencyList.Count)
            {
                throw new Exception($"Frequency and values quantity inconsistency!");
            }
            if (SetValue == null)
            {
                throw new ArgumentNullException(nameof(SetValue));
            }
            if (FrequencyBaseDict == null)
            {
                FrequencyBaseDict = new Dictionary<double, ObservableCollection<DataItem>>();
            }

            for (int i = 0; i < FrequencyList.Count; i++)
            {
                if (FrequencyBaseDict.Keys.Contains(FrequencyList[i]))
                {
                    //已经包含频点,更新
                    var Temp = FrequencyBaseDict[FrequencyList[i]];
                    if (Temp == null)
                    {
                        Temp = new ObservableCollection<DataItem>();
                        DataItem DataItem = new DataItem();
                        DataItem.Frequency = FrequencyList[i];
                        DataItem.Position = Position;
                        SetValue.Invoke(DataItem, Values[i]);
                        Temp.Add(DataItem);
                    }
                    else
                    {
                        var Items = Temp.Where(s => s.Position == Position);
                        if (Items == null)
                        {
                            //新增
                            DataItem DataItem = new DataItem();
                            DataItem.Frequency = FrequencyList[i];
                            DataItem.Position = Position;
                            SetValue.Invoke(DataItem, Values[i]);
                            Temp.Add(DataItem);
                        }
                        else if (Items.ToList().Count == 0)
                        {
                            //新增
                            DataItem DataItem = new DataItem();
                            DataItem.Frequency = FrequencyList[i];
                            DataItem.Position = Position;
                            SetValue.Invoke(DataItem, Values[i]);
                            Temp.Add(DataItem);
                        }
                        else if (Items.ToList().Count == 1)
                        {
                            //更新
                            DataItem DataItem = Items.First();
                            SetValue.Invoke(DataItem, Values[i]);
                        }
                        else if (Items.ToList().Count > 1)
                        {
                            //报错
                            throw new Exception("The same position count exceed 1!");
                        }
                    }
                }
                else
                {
                    //未包含频点,新增
                    DataItem DataItem = new DataItem();
                    DataItem.Frequency = FrequencyList[i];
                    DataItem.Position = Position;
                    SetValue.Invoke(DataItem, Values[i]);
                    FrequencyBaseDict.Add(FrequencyList[i], new ObservableCollection<DataItem>() { DataItem });
                }
            }
        }

        public static void BuildFrequencySpectrumDataItemList(double Position, List<double> FrequencyList, List<double> Values, ref List<DataItem> FrequencySpectrumDataItemList, Action<DataItem, double> SetValue)
        {
            if (Values == null)
            {
                throw new ArgumentNullException(nameof(Values));
            }
            if (FrequencyList == null)
            {
                throw new ArgumentNullException(nameof(FrequencyList));
            }
            if (Values.Count != FrequencyList.Count)
            {
                throw new Exception($"Frequency and values quantity inconsistency!");
            }
            if (SetValue == null)
            {
                throw new ArgumentNullException(nameof(SetValue));
            }
            if (FrequencySpectrumDataItemList == null)
            {
                FrequencySpectrumDataItemList = new List<DataItem>();
            }

            for (int i = 0; i < FrequencyList.Count; i++)
            {
                var Temps = FrequencySpectrumDataItemList.Where(s => s.Frequency == FrequencyList[i]);
                if (Temps == null)
                {
                    //增加
                    DataItem DataItem = new DataItem();
                    DataItem.Frequency = FrequencyList[i];
                    DataItem.Position = Position;
                    SetValue.Invoke(DataItem, Values[i]);
                    FrequencySpectrumDataItemList.Add(DataItem);
                }
                else if (Temps.ToList().Count == 0)
                {
                    //增加
                    DataItem DataItem = new DataItem();
                    DataItem.Frequency = FrequencyList[i];
                    DataItem.Position = Position;
                    SetValue.Invoke(DataItem, Values[i]);
                    FrequencySpectrumDataItemList.Add(DataItem);
                }
                else if (Temps.ToList().Count == 1)
                {
                    //修改
                    DataItem DataItem = Temps.First();
                    DataItem.Position = Position;
                    SetValue.Invoke(DataItem, Values[i]);
                }
                else if (Temps.ToList().Count == 2)
                {
                    //报错
                    throw new Exception($"The same frequency count exceed 1!");
                }
            }

            //剔除掉FrequencySpectrumDataItemList中除FrequencyList外的元素
            List<DataItem> Weed = new List<DataItem>();
            for (int i = 0; i < FrequencySpectrumDataItemList.Count; i++)
            {
                if (!FrequencyList.Contains(FrequencySpectrumDataItemList[i].Frequency))
                {
                    Weed.Add(FrequencySpectrumDataItemList[i]);
                }
            }
            foreach (DataItem Item in Weed)
            {
                FrequencySpectrumDataItemList.Remove(Item);
            }
        }

        public static void BuildFrequencySpectrumDataItemList2D(double Position1,double Position2, List<double> FrequencyList, List<double> Values, ref List<DataItem2D> FrequencySpectrumDataItemList, Action<DataItem2D, double> SetValue)
        {
            if (Values == null)
            {
                throw new ArgumentNullException(nameof(Values));
            }
            if (FrequencyList == null)
            {
                throw new ArgumentNullException(nameof(FrequencyList));
            }
            if (Values.Count != FrequencyList.Count)
            {
                throw new Exception($"Frequency and values quantity inconsistency!");
            }
            if (SetValue == null)
            {
                throw new ArgumentNullException(nameof(SetValue));
            }
            if (FrequencySpectrumDataItemList == null)
            {
                FrequencySpectrumDataItemList = new List<DataItem2D>();
            }

            for (int i = 0; i < FrequencyList.Count; i++)
            {
                var Temps = FrequencySpectrumDataItemList.Where(s => s.Frequency == FrequencyList[i]);
                if (Temps == null)
                {
                    //增加
                    DataItem2D DataItem2D = new DataItem2D();
                    DataItem2D.Frequency = FrequencyList[i];
                    DataItem2D.Position1 = Position1;
                    DataItem2D.Position2 = Position2;
                    SetValue.Invoke(DataItem2D, Values[i]);
                    FrequencySpectrumDataItemList.Add(DataItem2D);
                }
                else if (Temps.ToList().Count == 0)
                {
                    //增加
                    DataItem2D DataItem2D = new DataItem2D();
                    DataItem2D.Frequency = FrequencyList[i];
                    DataItem2D.Position1 = Position1;
                    DataItem2D.Position2 = Position2;
                    SetValue.Invoke(DataItem2D, Values[i]);
                    FrequencySpectrumDataItemList.Add(DataItem2D);
                }
                else if (Temps.ToList().Count == 1)
                {
                    //修改
                    DataItem2D DataItem2D = Temps.First();
                    DataItem2D.Position1 = Position1;
                    DataItem2D.Position2 = Position2;
                    SetValue.Invoke(DataItem2D, Values[i]);
                }
                else if (Temps.ToList().Count == 2)
                {
                    //报错
                    throw new Exception($"The same frequency count exceed 1!");
                }
            }

            //剔除掉FrequencySpectrumDataItemList中除FrequencyList外的元素
            List<DataItem2D> Weed = new List<DataItem2D>();
            for (int i = 0; i < FrequencySpectrumDataItemList.Count; i++)
            {
                if (!FrequencyList.Contains(FrequencySpectrumDataItemList[i].Frequency))
                {
                    Weed.Add(FrequencySpectrumDataItemList[i]);
                }
            }
            foreach (DataItem2D Item in Weed)
            {
                FrequencySpectrumDataItemList.Remove(Item);
            }
        }

        private static string PadRightEx(string str, int totalByteCount)
        {
            Regex regex = new Regex("[\u4e00-\u9fa5]");//匹配中文字符的正则表达式
            MatchCollection matchCollection = regex.Matches(str);//获取匹配的结果集合
            int dcount = matchCollection.Count;//获取匹配结果的数量


            int width = str.Length + dcount;
            string w = "";
            for (int i = 0; i < totalByteCount - width; i++)
            {
                w += " ";
            }
            w += str;
            return w;
        }
    }

    public class RealTimeCache
    {

        //数据队列，缓存数据
        private ConcurrentQueue<DataItem>? Cache;
        //缓存文件保存路径
        private string Path { get; set; } = System.AppDomain.CurrentDomain.BaseDirectory + "Data\\cache.txt";

        private bool CompletedFlag = false;

        //强行停止
        private bool StopFlag = false;

        //超时
        private int TimeOut_Min = 10;
        private bool TimeOutEnable = true;

        public void SetTimeOut(bool Enable, int TimeOut)
        {
            if (Enable)
            {
                TimeOutEnable = true;
                if (TimeOut < 1)
                {
                    TimeOut_Min = 1;
                }
                else
                {
                    TimeOut_Min = TimeOut;
                }
            }
            else
            {
                TimeOutEnable = false;
            }
        }


        public void Init(string SetPath = "")
        {
            if (!string.IsNullOrEmpty(SetPath))
            {
                Path = System.IO.Path.Combine(SetPath, "cache.txt");
            }

            if (System.IO.File.Exists(Path))
            {
                System.IO.File.Delete(Path);
            }

            //string[] Temps = Path.Split("\\");

            //System.IO.Directory.CreateDirectory(Path.Replace(Temps.Last(),""));
            //System.IO.File.Create(Path).Close();

            //创建文件头
            MeasureData MeasureData = new MeasureData();
            DataManage.WriteToFile(MeasureData, Path);



            CompletedFlag = false;
            StopFlag = false;
            Cache = new ConcurrentQueue<DataItem>();
            StartSave();
        }

        public void AddItem(DataItem Item)
        {
            if (Cache.Count > 800)
            {
                //队列太长会影响性能，所以队列长度不超过1000，出列1000条数据，需要1000ms
                Thread.Sleep(1000);
            }
            Cache?.Enqueue(Item);
        }

        public void AddCollection(ICollection<DataItem> Collection)
        {
            if (Collection == null) return;
            foreach (var Temp in Collection)
            {
                AddItem(Temp);
            }
        }

        public void Completed()
        {
            CompletedFlag = true;
        }

        public void Stop()
        {
            StopFlag = true;
        }

        //不断存储数据至硬盘,直至存储完毕，或停止
        private async void StartSave()
        {
            //string Data = "\n"; 
            string Data = "";
            object value;
            await Task.Run(() =>
            {
                StreamWriter StreamWriter = System.IO.File.AppendText(Path);

                while (!StopFlag)
                {
                    DataItem? DataItem = new DataItem();
                    DateTime Start = DateTime.Now;
                    while (!Cache.TryDequeue(out DataItem))
                    {
                        if (!string.IsNullOrEmpty(Data))
                        {
                            //文件操作太耗时，队列里没有数据，就等待，此时正好可以利用此时间间隙保存至硬盘
                            //取完队列中的数据，一次性保存
                            //将数据追加在缓存文件末尾
                            StreamWriter.Write(Data);
                            StreamWriter.Flush();

                            //清空Data
                            Data = "";
                        }
                        if (CompletedFlag && (Cache.Count == 0))
                        {
                            //throw new Exception("finished!");
                            //完成了
                            StreamWriter.Flush();
                            StreamWriter.Close();
                            StreamWriter.Dispose();
                            return;
                        }
                        if (StopFlag)
                        {
                            StreamWriter.Flush();
                            StreamWriter.Close();
                            StreamWriter.Dispose();
                            return;
                        }
                        Thread.Sleep(500); //避免一直轮询，造成资源无法释放，其他线程无法入列数据
                        DateTime Time = DateTime.Now;
                        if (TimeOutEnable)
                        {
                            if ((Time - Start).TotalMinutes > TimeOut_Min)
                            {
                                StreamWriter.Flush();
                                StreamWriter.Close();
                                StreamWriter.Dispose();
                                return; //等待了TimeOut_Min分钟，没有数据，则默认退出
                            }
                        }
                    }
                    //只处理数据
                    Type type = typeof(DataItem);
                    PropertyInfo[] PropertyInfo = type.GetProperties();
                    foreach (PropertyInfo Property in PropertyInfo)
                    {
                        value = Property.GetValue(DataItem, null);
                        if (value == null)
                        {
                            Data += ($"{"",25}");
                        }
                        else
                        {
                            Data += ($"{value.ToString(),25}");
                        }
                        Data += ",";
                    }
                    Data += "\n";
                }
                StreamWriter.Flush();
                StreamWriter.Close();
                StreamWriter.Dispose();
            });

        }
    }

    public class RealTimeCache2D
    {

        //数据队列，缓存数据
        private ConcurrentQueue<DataItem2D>? Cache;
        //缓存文件保存路径
        private string Path { get; set; } = System.AppDomain.CurrentDomain.BaseDirectory + "Data\\cache.txt";

        private bool CompletedFlag = false;

        //强行停止
        private bool StopFlag = false;

        //超时
        private int TimeOut_Min = 10;
        private bool TimeOutEnable = true;

        public void SetTimeOut(bool Enable, int TimeOut)
        {
            if (Enable)
            {
                TimeOutEnable = true;
                if (TimeOut < 1)
                {
                    TimeOut_Min = 1;
                }
                else
                {
                    TimeOut_Min = TimeOut;
                }
            }
            else
            {
                TimeOutEnable = false;
            }
        }


        public void Init(string SetPath = "")
        {
            if (!string.IsNullOrEmpty(SetPath))
            {
                Path = System.IO.Path.Combine(SetPath, "cache.txt");
            }

            if (System.IO.File.Exists(Path))
            {
                System.IO.File.Delete(Path);
            }

            //string[] Temps = Path.Split("\\");

            //System.IO.Directory.CreateDirectory(Path.Replace(Temps.Last(),""));
            //System.IO.File.Create(Path).Close();

            //创建文件头
            MeasureData2D MeasureData2D = new MeasureData2D();
            DataManage.WriteToFile(MeasureData2D, Path);



            CompletedFlag = false;
            StopFlag = false;
            Cache = new ConcurrentQueue<DataItem2D>();
            StartSave();
        }

        public void AddItem(DataItem2D Item)
        {
            if (Cache.Count > 800)
            {
                //队列太长会影响性能，所以队列长度不超过1000，出列1000条数据，需要1000ms
                Thread.Sleep(1000);
            }
            Cache?.Enqueue(Item);
        }

        public void AddCollection(ICollection<DataItem2D> Collection)
        {
            if (Collection == null) return;
            foreach (var Temp in Collection)
            {
                AddItem(Temp);
            }
        }

        public void Completed()
        {
            CompletedFlag = true;
        }

        public void Stop()
        {
            StopFlag = true;
        }

        //不断存储数据至硬盘,直至存储完毕，或停止
        private async void StartSave()
        {
            //string Data = "\n"; 
            string Data = "";
            object value;
            await Task.Run(() =>
            {
                StreamWriter StreamWriter = System.IO.File.AppendText(Path);

                while (!StopFlag)
                {
                    DataItem2D? DataItem2D = new DataItem2D();
                    DateTime Start = DateTime.Now;
                    while (!Cache.TryDequeue(out DataItem2D))
                    {
                        if (!string.IsNullOrEmpty(Data))
                        {
                            //文件操作太耗时，队列里没有数据，就等待，此时正好可以利用此时间间隙保存至硬盘
                            //取完队列中的数据，一次性保存
                            //将数据追加在缓存文件末尾
                            StreamWriter.Write(Data);
                            StreamWriter.Flush();

                            //清空Data
                            Data = "";
                        }
                        if (CompletedFlag && (Cache.Count == 0))
                        {
                            //throw new Exception("finished!");
                            //完成了
                            StreamWriter.Flush();
                            StreamWriter.Close();
                            StreamWriter.Dispose();
                            return;
                        }
                        if (StopFlag)
                        {
                            StreamWriter.Flush();
                            StreamWriter.Close();
                            StreamWriter.Dispose();
                            return;
                        }
                        Thread.Sleep(500); //避免一直轮询，造成资源无法释放，其他线程无法入列数据
                        DateTime Time = DateTime.Now;
                        if (TimeOutEnable)
                        {
                            if ((Time - Start).TotalMinutes > TimeOut_Min)
                            {
                                StreamWriter.Flush();
                                StreamWriter.Close();
                                StreamWriter.Dispose();
                                return; //等待了TimeOut_Min分钟，没有数据，则默认退出
                            }
                        }
                    }
                    //只处理数据
                    Type type = typeof(DataItem);
                    PropertyInfo[] PropertyInfo = type.GetProperties();
                    foreach (PropertyInfo Property in PropertyInfo)
                    {
                        value = Property.GetValue(DataItem2D, null);
                        if (value == null)
                        {
                            Data += ($"{"",25}");
                        }
                        else
                        {
                            Data += ($"{value.ToString(),25}");
                        }
                        Data += ",";
                    }
                    Data += "\n";
                }
                StreamWriter.Flush();
                StreamWriter.Close();
                StreamWriter.Dispose();
            });

        }
    }
}
